home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / emmpas.zip / ASEMS.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  28KB  |  656 lines

  1. {$O+,F+} { Allow Overlays                   }
  2. {$R-}    { No range checking                }
  3. {$S-}    { No stack checking                }
  4. {$I-}    { No I/O checking                  }
  5. {$V-}    { No string checking               }
  6. {$B-}    { Boolean short circuit evaluation }
  7. {$N-}    { No numeric coprocessor           }
  8. {$D-}    { No debug information             }
  9.  
  10. Unit ASEMS;  { Unit name to include in the uses clause of your program }
  11.  
  12. (*┌────────────────────────────────────────────────────────────────────────┐
  13.   │┌ base address                            If you have 256K of LIM EMS   │
  14.   │└┬─────────────────┐  ┌─────────────────┐ the logical pages will be     │
  15.   │ │ physical page 0 ├──┤ logical page 0  │ numbered 0 through   - number │
  16.   │ ├─────────────────┤  ├─────────────────┤ that you allocate.  When you  │
  17.   │ │ physical page 1 ├──┤ logical page 1  │ specify an address in EMS     │
  18.   │ ├─────────────────┤  ├─────────────────┤ you are actually addressing   │
  19.   │ │ physical page 2 ├──┤ logical page 2  │ an area in the physical page  │
  20.   │ ├─────────────────┤  ├─────────────────┤ array, and you will access    │
  21.   │ │ physical page 3 ├──┤ logical page 3  │ any variables in the logical  │
  22.   │ └──┬──────────────┘  ├─────────────────┤ pages that are currently      │
  23.   │    │                 │ logical page 4  │ mapped to that array.  In this│
  24.   │ In the 3.2 LIM the   ├─────────────────┤ example physical pages 0 - 3  │
  25.   │ physical pages are   │ logical page 5  │ are mapped to logical 0 - 3.  │
  26.   │ located in the 1Byte ├─────────────────┤ If you wish to access data    │
  27.   │ of address space     │ logical page 6  │ structures larger than 64K,   │
  28.   │ allowed by the       ├─────────────────┤ you need to remap to other    │
  29.   │ microprocessor and   │ logical page 7  │ logical pages.  In the demo   │
  30.   │ above the 640K       ├─────────────────┤ program, 8 logical pages 0 - 7│
  31.   │ boundary.  The       │ logical page 8  │ are allocated and a 128K      │
  32.   │ Address of the       ├─────────────────┤ array of 80 character strings │
  33.   │ physical page array  │ logical page 9  │ is allocated to EMS memory.   │
  34.   │ is dependent on the  ├─────────────────┤                               │
  35.   │ hardware.            │ logical page 10 │                               │
  36.   │ MapAndTestPages will ├─────────────────┤                               │
  37.   │ return the base      │ logical page 11 │                               │
  38.   │ address of the       ├─────────────────┤                               │
  39.   │ physical page array. │ logical page 12 │                               │
  40.   │                      ├─────────────────┤                               │
  41.   │                      │ logical page 13 │                               │
  42.   │                      ├─────────────────┤                               │
  43.   │                      │ logical page 14 │                               │
  44.   │                      ├─────────────────┤                               │
  45.   │                      │ logical page 15 │                               │
  46.   │                      ├─────────────────┤                               │
  47.   │                      │ logical page 16 │                               │
  48.   │                      └─────────────────┘                               │
  49.   └────────────────────────────────────────────────────────────────────────┘*)
  50. (*┌──────────────────────────────────────────────────────────────────────────┐
  51.   │ This is all you really need to use EMS memory for dynamically allocated  │
  52.   │ variables.  Function 15 adds storage of mapping context which you can    │
  53.   │ do in a case statement with the Remap function.  If you wish to write    │
  54.   │ programs for wide usage then it is best to keep with 3.2 compatibility   │
  55.   │ since it is a subset of the 4.0 standard.   Turbo Pascal already has     │
  56.   │ facility for executing code in EMS memory.  You may need to add 4.0 calls│
  57.   │ if you wish to swap memory regions between an EMS page mapping context   │
  58.   │ and the heap within conventional memory.                                 │
  59.   └──────────────────────────────────────────────────────────────────────────┘*)
  60. INTERFACE
  61. USES CRT, DOS;
  62.  
  63. TYPE
  64.  
  65.   Str3  = STRING [ 03 ];
  66.   Str55 = STRING [ 55 ];
  67.   Str5 =  STRING [ 05 ];
  68.  
  69. CONST
  70.  
  71.   LIMInterrupt                      = $67;  { EMM services INTR  }
  72.   DosInterrupt                      = $21;  { DOS services INTR  }
  73.   GetStatus                         = $40;  { EMS 3.2 function 1 }
  74.   GetPageFrame                      = $41;  { EMS 3.2 function 2 }
  75.   GetUnallocatedPageCount           = $42;  { EMS 3.2 function 3 }
  76.   AllocatePages                     = $43;  { EMS 3.2 function 4 }
  77.   MapPages                          = $44;  { EMS 3.2 function 5 }
  78.   DeAllocatePages                   = $45;  { EMS 3.2 function 6 }
  79.   GetVersion                        = $46;  { EMS 3.2 function 7 }
  80.   SavePageMap                       = $47;  { EMS 3.2 function 8 }
  81.   RestorePageMap                    = $48;  { EMS 3.2 function 9 }
  82.   GetHandleCount                    = $4B;  { EMS 3.2 function 12 }
  83.   GetHandlePages                    = $4C;  { EMS 3.2 function 13 }
  84.  
  85.   StatusOk                          = 0;    { EMS 3.2 status     }
  86.  
  87. (*┌────────────────────────────────────────────────────────────────────────┐
  88.   │FUNCTION:  HexString ( Number : WORD ) : Str5;                          │
  89.   │                                                                        │
  90.   │PURPOSE: Converts a word value : Number to a 5 character string which   │
  91.   │is the return value of the function.                                    │
  92.   │DESCRIPTION:  Parses number for each character in the string and        │
  93.   │appends characters to the output string.                                │
  94.   │INPUT: A word value.                                                    │
  95.   │OUTPUT: A five character string which can be displayed.                 │
  96.   └────────────────────────────────────────────────────────────────────────┘*)
  97. (*┌────────────────────────────────────────────────────────────────────────┐
  98.   │FUNCTION: LIMInstalled : BOOLEAN;                                       │
  99.   │PURPOSE: Tests for presence of EMM                                      │
  100.   │DESCRIPTION: Checks to see if EMM is installed by looking for the       │
  101.   │string 'EMMXXXX0', which is located 10 bytes from the beginning of the  │
  102.   │code segment pointed to by the LIM interrupt $67                        │
  103.   │OUTPUT:  BOOLEAN, TRUE if installed                                     │
  104.   └────────────────────────────────────────────────────────────────────────┘*)
  105. (*┌────────────────────────────────────────────────────────────────────────┐
  106.   │FUNCTION:  EMMVersion ( VAR VersionStr : Str3 ) : WORD;                 │
  107.   │                                                                        │
  108.   │PURPOSE:  Return the Version number as a 3 character string and         │
  109.   │the function value returns the error code                               │
  110.   │                                                                        │
  111.   │OUTPUT: Version String and errorcode                                    │
  112.   └────────────────────────────────────────────────────────────────────────┘*)
  113. (*┌────────────────────────────────────────────────────────────────────────┐
  114.   │FUNCTION :  EMMError       ( ErrorNumber : WORD ) : Str55;              │
  115.   │PURPOSE:  To find an error string from a error number                   │
  116.   │INPUT:  Error number as a word                                          │
  117.   │OUTPUT: Error string of type Str55                                      │
  118.   └────────────────────────────────────────────────────────────────────────┘*)
  119. (*┌────────────────────────────────────────────────────────────────────────┐
  120.   │FUNCTION:  MapAndTestPages ( NumberOfPages, L1, L2, L3, L4 : WORD;      │
  121.   │                             VAR Handle, Address : WORD;                │
  122.   │                             VAR Error : Str55 ) : BOOLEAN;             │
  123.   │PURPOSE:  This is a complex function which tests for the presence of    │
  124.   │LIM EMS memory and then for the version.  If the version is 3.2 or above│
  125.   │and sufficient pages exist for the request, NumberOfPages are allocated │
  126.   │and then physical pages 0, 1, 2, 3 are mapped to logical pages L1, L2,  │
  127.   │L3, and L4 as specified by the user.  The function returns a handle     │
  128.   │and the address of the base of the page physical page frame.  The       │
  129.   │function will return FALSE if any of the requests fail and an error     │
  130.   │string of type Str55 will be returned.                                  │
  131.   │INPUT:  The number of 16K pages you are requesting, the four logical    │
  132.   │pages you are mapping the four physical pages to.                       │
  133.   │OUTPUT:  An assigned handle and the base segment address of the physical│
  134.   │page frame.  If there is an error the function will return false and    │
  135.   │an error string of type Str55 will be passed to the calling program.    │
  136.   └────────────────────────────────────────────────────────────────────────┘*)
  137. (*┌────────────────────────────────────────────────────────────────────────┐
  138.   │FUNCTION: ReleaseHandle ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN; │
  139.   │                                                                        │
  140.   │PURPOSE:  Release EMS memory for the specified handle.                  │
  141.   │INPUT:  Handle                                                          │
  142.   │OUTPUT: If not successful: returns error string of type Str55 and the   │
  143.   │function returns FALSE                                                  │
  144.   └────────────────────────────────────────────────────────────────────────┘*)
  145. (*┌────────────────────────────────────────────────────────────────────────┐
  146.   │FUNCTION: Remap ( L1, L2, L3, L4, Handle : WORD; VAR Error : Str55 ) :  │
  147.   │                  BOOLEAN;                                              │
  148.   │PURPOSE:  Used to remap physical pages 0 - 3 to the specified logical   │
  149.   │pages.                                                                  │
  150.   │INPUT: Numbers of the four logical pages and handle.                    │
  151.   │OUTPUT: Returns FALSE if not successful and an error string of type     │
  152.   │Str55.                                                                  │
  153.   └────────────────────────────────────────────────────────────────────────┘*)
  154. (*┌────────────────────────────────────────────────────────────────────────┐
  155.   │FUNCTION:  SaveMap ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;      │
  156.   │PURPOSE:  Saves the context of the present page map for later restore.  │
  157.   │INPUT:  Handle                                                          │
  158.   │OUTPUT:  Returns FALSE if unsuccessful and an error string of type Str55│
  159.   └────────────────────────────────────────────────────────────────────────┘*)
  160. (*┌────────────────────────────────────────────────────────────────────────┐
  161.   │FUNCTION: RestoreMap ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;    │
  162.   │PURPOSE: Restores the context of the page map.                          │
  163.   │INPUT:  Handle                                                          │
  164.   │OUTPUT:  Returns FALSE if unsuccessful and an error string of type Str55│
  165.   └────────────────────────────────────────────────────────────────────────┘*)
  166. (*┌────────────────────────────────────────────────────────────────────────┐
  167.   │FUNCTION: HandleCount( VAR Number : WORD; VAR Error : Str55 ) : BOOLEAN;│
  168.   │PURPOSE: Returns the number of handles in use by EEM.                   │
  169.   │INPUT:  NONE                                                            │
  170.   │OUTPUT:  Returns FALSE if unsuccessful and an error string of type Str55│
  171.   │Passes to the calling program the number of handle in use.              │
  172.   └────────────────────────────────────────────────────────────────────────┘*)
  173. (*┌────────────────────────────────────────────────────────────────────────┐
  174.   │FUNCTION: HandleCount( VAR Handle, Number : WORD; VAR Error : Str55 )   │
  175.   │                                                              : BOOLEAN;│
  176.   │PURPOSE: Returns the number of pages in use by the specified handle.    │
  177.   │INPUT:  Handle                                                          │
  178.   │OUTPUT:  Returns FALSE if unsuccessful and an error string of type Str55│
  179.   │Passes to the calling program the number of pages used by handle.       │
  180.   └────────────────────────────────────────────────────────────────────────┘*)
  181. (*┌────────────────────────────────────────────────────────────────────────┐
  182.   │FUNCTION: GetMappingSize( VAR Bytes : WORD; VAR Error : Str55 )         │
  183.   │                                                              : BOOLEAN;│
  184.   │PURPOSE: Returns the number of bytes required for the page mapping.     │
  185.   │INPUT:  NONE                                                            │
  186.   │OUTPUT:  Returns FALSE if unsuccessful and an error string of type Str55│
  187.   │Passes to the calling program the number bytes required to save mapping.│
  188.   └────────────────────────────────────────────────────────────────────────┘*)
  189. (*┌────────────────────────────────────────────────────────────────────────┐
  190.   │FUNCTION: GetMap ( VAR Seg, Ofs     : WORD; VAR Error : Str55 )         │
  191.   │                                                              : BOOLEAN;│
  192.   │PURPOSE: Gets the present page mapping and outputs the array to the     │
  193.   │address given in the ES:DI pair.                                        │
  194.   │INPUT:  ES:DI pointer to mapping array.                                 │
  195.   │OUTPUT:  Returns FALSE if unsuccessful and an error string of type Str55│
  196.   │Passes to the calling program the mapping area address.                 │
  197.   └────────────────────────────────────────────────────────────────────────┘*)
  198.  
  199. FUNCTION MapAndTestPages
  200. ( NumberofPages, L1, L2, L3, L4 : WORD; VAR Handle, Address : WORD;
  201.   VAR Error : Str55 ) : BOOLEAN;
  202.  
  203. FUNCTION ReleaseHandle ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  204.  
  205. FUNCTION HexString ( Number : WORD ): Str5;
  206.  
  207. FUNCTION EMMVersion ( VAR VersionStr : Str3 ) : WORD;
  208.  
  209. FUNCTION ReMap ( L1, L2, L3, L4, Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  210.  
  211. FUNCTION SaveMap ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  212.  
  213. FUNCTION RestoreMap ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  214.  
  215. FUNCTION HandleCount ( VAR Number : WORD; VAR Error : Str55 ) : BOOLEAN;
  216.  
  217. FUNCTION HandlePages ( VAR Handle, Number : WORD; VAR Error : Str55 ) : BOOLEAN;
  218.  
  219. FUNCTION GetMappingSize ( Bytes : WORD; VAR Error : Str55 ) : BOOLEAN;
  220.  
  221.  
  222. IMPLEMENTATION
  223.  
  224.  
  225. FUNCTION   HexString ( Number : WORD ): Str5;
  226.     FUNCTION HexChar ( Number: Word ):  CHAR;
  227.     BEGIN
  228.       IF Number < 10 THEN
  229.         HexChar := CHAR ( Number + 48 )
  230.       ELSE
  231.         HexChar := CHAR ( Number + 55 );
  232.     END;
  233. VAR
  234. S : Str5;
  235.   BEGIN
  236.     S := '';
  237.     S := HexChar ( ( Number SHR 1 ) DIV 2048 );
  238.     Number := ( ( ( Number SHR 1 ) MOD 2048 ) SHL 1 ) +
  239.             ( Number AND 1 ) ;
  240.     S := S + HexChar ( Number DIV 256 );
  241.     Number := Number MOD 256;
  242.     S := S + HexChar ( Number DIV 16 );
  243.     Number := Number MOD 16;
  244.     S := S + HexChar ( Number );
  245.     HexString := S + 'h';
  246. END;
  247.  
  248.  
  249. FUNCTION LIMInstalled : BOOLEAN;
  250. VAR
  251. TestName              : STRING [ 8 ];
  252. DeviceName            : STRING [ 8 ];
  253. Position              : WORD;
  254. Regs                  : REGISTERS;
  255.  
  256. BEGIN
  257.     DeviceName          :=  '';
  258.     TestName            :=  'EMMXXXX0';
  259.     WITH Regs DO
  260.     BEGIN
  261.       AH := $35;                 { Dos call $35 Get Interrupt Vector }
  262.       AL := LIMInterrupt;
  263.       INTR ( DosInterrupt, Regs );
  264.       Position := Regs.ES;
  265.  
  266. { The ES register pair contains the segment address of ISR 67h }
  267. { Find string at position pointed to by the ES pair }
  268.  
  269.       FOR Position := 0 to 7 DO
  270.         DeviceName := DeviceName + CHR ( MEM [ ES : Position + $0A ] );
  271.         LIMInstalled    :=  TRUE;   { Set BOOLEAN TRUE before test }
  272.  
  273.     END;
  274.       { Is it the EMM manager signature, 'EMMXXXX0'? then EMM is
  275.         installed and ready for use, if not, then the EMM manager
  276.         is not present                                            }
  277.       IF DeviceName <> TestName THEN LIMInstalled  :=  FALSE;
  278. END;
  279.  
  280. FUNCTION EMMVersion ( VAR VersionStr : Str3 ) : WORD;
  281. VAR
  282. Regs           : REGISTERS;
  283. Major,
  284. Minor          : CHAR;
  285. BEGIN
  286.       Regs.AH := GetVersion;
  287.       INTR ( LimInterrupt, Regs );
  288.       EMMVersion := Regs.AH;
  289.       IF Regs.AH = StatusOk THEN
  290.       BEGIN
  291.         Major   := CHAR ( Regs.AL SHR 4 + 48 );
  292.         Minor   := CHAR ( Regs.AL AND $F + 48 );
  293.         VersionStr := Major + '.' + Minor;
  294.       END;
  295. END;
  296. FUNCTION EMMError ( ErrorNumber: WORD ) : Str55;
  297.   BEGIN
  298.  
  299.     EMMError := '';
  300.  
  301.     CASE ErrorNumber OF
  302.  
  303.     $80 : EMMError := 'EMM driver software failure';
  304.     $81 : EMMError := 'EMM driver detected hardware failure';
  305.     $82 : EMMError := 'EMM driver busy';
  306.     $83 : EMMError := 'Cannot find the specified handle';
  307.     $84 : EMMError := 'Undefined function code';
  308.     $85 : EMMError := 'No handles are currently available';
  309.     $86 : EMMError := 'Mapping context restoration error ';
  310.     $87 : EMMError := 'Insufficient total pages for request';
  311.     $88 : EMMError := 'Insufficient unallocated pages';
  312.     $89 : EMMError := 'Zero logical pages have been requested';
  313.     $8A : EMMError := 'Logical page out of range for handle';
  314.     $8B : EMMError := 'Physical Page out of range';
  315.     $8C : EMMError := 'Mapping register context area is full';
  316.     $8D : EMMError := 'Stack has context associated with handle';
  317.     $8E : EMMError := 'Stack has no context associated with handle';
  318.     $8F : EMMError := 'Undefined subfunction request';
  319.     $90 : EMMError := 'Attribute type undefined';
  320.     $91 : EMMError := 'System does not support nonvolatility';
  321.     $92 : EMMError := 'Partial source overwrite during move';
  322.     $93 : EMMError := 'EMS region too big for handle';
  323.     $94 : EMMError := 'Conventional and EMS memory region overlap';
  324.     $95 : EMMError := 'Offset in logical page exceeds limit';
  325.     $96 : EMMError := 'Region exceeds 1 MByte limit';
  326.     $97 : EMMError := 'Src and Dest EMS regions use same handle/overlap';
  327.     $98 : EMMError := 'Undefined memory source and destination types';
  328.     $9A : EMMError := 'Specified alternate map register set not extant';
  329.     $9B : EMMError := 'All alternate map/DMA register sets in use';
  330.     $9C : EMMError := 'Alternate map/DMA register sets not supported';
  331.     $9D : EMMError := 'Alternate map/DMA not defined, allocated or is current';
  332.     $9E : EMMError := 'Dedicated DMA channels are not supported';
  333.     $9F : EMMError := 'Dedicated DMA channel not extant';
  334.     $A0 : EMMError := 'No handle found for handle name';
  335.     $A1 : EMMError := 'A handle by that name exists';
  336.     $A2 : EMMError := 'Attempt to wrap around the 1Mbyte space during move';
  337.     $A3 : EMMError := 'Contents of user structure passed was corrupt';
  338.     $A4 : EMMError := 'Operating system denied access to function';
  339.  
  340.     END;
  341. END;
  342.  
  343. FUNCTION MapAndTestPages
  344. ( NumberofPages, L1, L2, L3, L4 : WORD; VAR Handle, Address : WORD;
  345.   VAR Error : Str55 ) : BOOLEAN;
  346.  
  347. VAR
  348. Regs        : REGISTERS;
  349. EMMVer      : Str3;
  350. VerOk       : BOOLEAN;
  351. ValueStr    : STRING;
  352. StatsTest   : WORD;
  353. code        : INTEGER;
  354. RealVer     : REAL;
  355.  
  356. BEGIN
  357.  Error := '';
  358.  MapAndTestPages := TRUE;
  359.  IF NOT LimInstalled THEN
  360.  BEGIN
  361.    MapAndTestPages := FALSE;
  362.    Error := 'LIM Expanded Memory Manager not installed';
  363.  END;
  364.   IF LimInstalled THEN
  365.     BEGIN
  366.       VerOk      := FALSE;
  367.       StatsTest  := EMMVersion ( EMMVer );
  368.       IF StatsTest <> StatusOk THEN
  369.       BEGIN
  370.       MapAndTestPages := FALSE;
  371.       Error := EMMError ( StatsTest );
  372.       END;
  373.       IF StatsTest = StatusOk THEN
  374.         BEGIN
  375.         ValueStr   := EMMVer;
  376.         VAL        ( ValueStr, RealVer, code );
  377.  
  378.         IF ( RealVer < 3.1 ) THEN
  379.         BEGIN
  380.         MapAndTestPages := FALSE;
  381.         Error := 'LIM EMM version earlier than 3.2';
  382.         END;
  383.           IF ( RealVer >= 3.1 ) THEN
  384.             BEGIN
  385.               Regs.AH := GetStatus;
  386.               INTR ( LIMInterrupt, Regs );
  387.               IF Regs.AH <> StatusOk THEN
  388.               BEGIN
  389.               MapAndTestPages := FALSE;
  390.               Error := EMMError ( Regs.AH );
  391.               END;
  392.               IF Regs.AH = StatusOk THEN
  393.                 BEGIN
  394.                   Regs.AH := GetUnallocatedPageCount;
  395.                   INTR    ( LIMInterrupt, Regs );
  396.  
  397.                   IF Regs.AH <> StatusOk THEN
  398.                   BEGIN
  399.                   MapAndTestPages := FALSE;
  400.                   Error := EMMError ( Regs.AH );
  401.                   END;
  402.  
  403.                   IF ( Regs.AH = StatusOk ) AND ( Regs.BX < NumberOfPages ) THEN
  404.                   MapAndTestPages := FALSE;
  405.  
  406.                   IF ( Regs.AH = StatusOk ) AND ( Regs.BX >= NumberOfPages ) THEN
  407.  
  408.                     BEGIN
  409.                       Regs.AH := AllocatePages;
  410.                       Regs.BX := NumberOfPages;
  411.                       INTR ( LIMInterrupt, Regs );
  412.                       Handle  := Regs.DX;
  413.                       IF Regs.AH <> StatusOk THEN
  414.                       BEGIN
  415.                       MapAndTestPages := FALSE;
  416.                       Error := EMMError ( Regs.AH );
  417.                       END;
  418.                       IF Regs.AH = StatusOk THEN
  419.                                                 BEGIN
  420.                           Regs.AH := MapPages;
  421.                           Regs.AL := 0;     { Physical Page }
  422.                           Regs.BX := L1;     { Logical Page  }
  423.                                                     Regs.DX := Handle;
  424.                                                     INTR ( LIMInterrupt, Regs );
  425.  
  426.                           IF Regs.AH <> StatusOk THEN
  427.                           BEGIN
  428.                           MapAndTestPages := FALSE;
  429.                           Error := EMMError ( Regs.AH );
  430.                           END;
  431.                                                     IF Regs.AH = StatusOk THEN
  432.                             BEGIN
  433.                               Regs.AH := MapPages;
  434.                               Regs.AL := 1;
  435.                               Regs.BX := L2;
  436.                               Regs.DX := Handle;
  437.                               INTR ( LIMInterrupt, Regs );
  438.                               IF Regs.AH <> StatusOk THEN
  439.                               BEGIN
  440.                               MapAndTestPages := FALSE;
  441.                               Error := EMMError ( Regs.AH );
  442.                               END;
  443.                               IF Regs.AH = StatusOk THEN
  444.                                 BEGIN
  445.                                   Regs.AH := MapPages;
  446.                                   Regs.AL := 2;
  447.                                   Regs.BX := L3;
  448.                                   Regs.DX := Handle;
  449.                                   INTR ( LIMInterrupt, Regs );
  450.  
  451.                                   IF Regs.AH <> StatusOk THEN
  452.                                   BEGIN
  453.                                   MapAndTestPages := FALSE;
  454.                                   Error := EMMError ( Regs.AH );
  455.                                   END;
  456.                                   IF Regs.AH = StatusOk THEN
  457.                                     BEGIN
  458.                                       Regs.AH := MapPages;
  459.                                       Regs.AL := 3;
  460.                                       Regs.BX := L4;
  461.                                       Regs.DX := Handle;
  462.                                       INTR ( LIMInterrupt, Regs );
  463.                                       IF Regs.AH <> StatusOk THEN
  464.                                       BEGIN
  465.                                       MapAndTestPages := FALSE;
  466.                                       Error := EMMError ( Regs.AH );
  467.                                       END;
  468.  
  469.                                       IF Regs.AH = StatusOk THEN
  470.                                         BEGIN
  471.                                           Regs.AH := GetPageFrame;
  472.                                           INTR ( LIMInterrupt, Regs );
  473.                                           Address := Regs.BX;
  474.  
  475.                                         END;
  476.                                     END;
  477.                                 END;
  478.                             END;
  479.                         END;
  480.                     END;
  481.                 END;
  482.             END;
  483.         END;
  484.     END;
  485. END;
  486. FUNCTION ReleaseHandle ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  487.  
  488. VAR
  489. Regs : REGISTERS;
  490.  
  491. BEGIN
  492. ReleaseHandle := TRUE;
  493. Regs.AH := DeallocatePages;
  494. Regs.DX := Handle;
  495. INTR ( LIMInterrupt, Regs );
  496.  
  497.   IF Regs.AH <> StatusOk THEN
  498.   BEGIN
  499.     ReleaseHandle := FALSE;
  500.     Error := EMMError ( Regs.AH );
  501.   END;
  502. END;
  503. FUNCTION ReMap ( L1, L2, L3, L4, Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  504. VAR
  505. Regs : REGISTERS;
  506.  
  507. BEGIN
  508. Remap := TRUE;
  509. Regs.AH := MapPages;
  510. Regs.AL := 0;      { Physical Page }
  511. Regs.BX := L1;     { Logical Page  }
  512. Regs.DX := Handle;
  513. INTR ( LIMInterrupt, Regs );
  514. IF Regs.AH <> StatusOk THEN
  515. BEGIN
  516. Remap := FALSE;
  517. Error := EMMError ( Regs.AH );
  518. END;
  519. IF Regs.AH = StatusOk THEN
  520.   BEGIN
  521.     Regs.AH := MapPages;
  522.     Regs.AL := 1;
  523.     Regs.BX := L2;
  524.     Regs.DX := Handle;
  525.     INTR ( LIMInterrupt, Regs );
  526.     IF Regs.AH <> StatusOk THEN
  527.     BEGIN
  528.     Remap := FALSE;
  529.     Error := EMMError ( Regs.AH );
  530.     END;
  531.     IF Regs.AH = StatusOk THEN
  532.       BEGIN
  533.         Regs.AH := MapPages;
  534.         Regs.AL := 2;
  535.         Regs.BX := L3;
  536.         Regs.DX := Handle;
  537.         INTR ( LIMInterrupt, Regs );
  538.         IF Regs.AH <> StatusOk THEN
  539.         BEGIN
  540.         Remap := FALSE;
  541.         Error := EMMError ( Regs.AH );
  542.         END;
  543.         IF Regs.AH = StatusOk THEN
  544.           BEGIN
  545.             Regs.AH := MapPages;
  546.             Regs.AL := 3;
  547.             Regs.BX := L4;
  548.             Regs.DX := Handle;
  549.             INTR ( LIMInterrupt, Regs );
  550.             IF Regs.AH <> StatusOk THEN
  551.             BEGIN
  552.             Remap := FALSE;
  553.             Error := EMMError ( Regs.AH );
  554.             END;
  555.  
  556.           END;
  557.       END;
  558.   END;
  559. END;
  560.  
  561. FUNCTION SaveMap ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  562. VAR
  563. Regs : REGISTERS;
  564.  
  565. BEGIN
  566. SaveMap := TRUE;
  567. Regs.AH := SavePageMap;
  568. Regs.DX := Handle;
  569. INTR ( LIMInterrupt, Regs );
  570. IF Regs.AH <> StatusOk THEN
  571. BEGIN
  572. SaveMap := FALSE;
  573. Error   := EMMError ( Regs.AH );
  574. END;
  575. END;
  576.  
  577. FUNCTION RestoreMap ( Handle : WORD; VAR Error : Str55 ) : BOOLEAN;
  578. VAR
  579. Regs : REGISTERS;
  580.  
  581. BEGIN
  582. RestoreMap := TRUE;
  583. Regs.AH := RestorePageMap;
  584. Regs.DX := Handle;
  585. INTR ( LIMInterrupt, Regs );
  586. IF Regs.AH <> StatusOk THEN
  587. BEGIN
  588. RestoreMap := FALSE;
  589. Error := EMMError ( Regs.AH );
  590. END;
  591. END;
  592. FUNCTION HandleCount ( VAR Number : WORD; VAR Error : Str55 ) : BOOLEAN;
  593. VAR
  594. Regs : REGISTERS;
  595. BEGIN
  596. HandleCount := TRUE;
  597. Regs.AH := GetHandleCount;
  598. INTR ( LIMInterrupt, Regs );
  599. Number := Regs.BX;
  600. IF Regs.AH <> StatusOk THEN
  601. BEGIN
  602. HandleCount := FALSE;
  603. Error := EMMError ( Regs.AH );
  604. END;
  605. END;
  606.  
  607. FUNCTION HandlePages ( VAR Handle, Number : WORD; VAR Error : Str55 ) : BOOLEAN;
  608. VAR
  609. Regs : REGISTERS;
  610. BEGIN
  611. HandlePages := TRUE;
  612. Regs.AH := GetHandlePages;
  613. Regs.DX := Handle;
  614. INTR ( LIMInterrupt, Regs );
  615. Number := Regs.BX;
  616. IF Regs.AH <> StatusOk THEN
  617. BEGIN
  618. HandlePages := FALSE;
  619. Error := EMMError ( Regs.AH );
  620. END;
  621. END;
  622.  
  623. FUNCTION GetMappingSize ( Bytes : WORD; VAR Error : Str55 ) : BOOLEAN;
  624. VAR
  625. Regs : REGISTERS;
  626. BEGIN
  627. GetMappingSize := TRUE;
  628. Regs.AX := $4E03;
  629. INTR ( LIMInterrupt, Regs );
  630. Bytes := Regs.AX;
  631. IF Regs.AH <> StatusOk THEN
  632. BEGIN
  633. GetMappingSize := FALSE;
  634. Error := EMMError ( Regs.AH );
  635. END;
  636. END;
  637.  
  638. FUNCTION GetMap ( VAR Seg, Ofs: WORD; VAR Error : Str55 ) : BOOLEAN;
  639. VAR
  640. Regs : REGISTERS;
  641. BEGIN
  642. GetMap := TRUE;
  643. Regs.AX := $4E00;
  644. INTR ( LIMInterrupt, Regs );
  645. Regs.ES := Seg;
  646. Regs.Di := Ofs;
  647. IF Regs.AH <> StatusOk THEN
  648. BEGIN
  649. GetMap := FALSE;
  650. Error := EMMError ( Regs.AH );
  651. END;
  652. END;
  653.  
  654. END.
  655.  
  656.